
#ifndef AXIS_H
#define AXIS_H

#include <QDebug>
#include <QList>
#include <QMap>
#include <QMouseEvent>
#include <QPoint>
#include <QVector2D>
#include <QVector>
#include <QWheelEvent>
#include <QtMath>
#include <cmath>
#include <map>
#include <vector>


namespace qgraphic {

struct Point {
    double x, y;
    Point() : x(0), y(0){};
    Point(double x, double y) : x(x), y(y){};
    double distance(Point t) {
        return sqrt(pow(x - t.x, 2) + pow(y - t.y, 2));
    };
};

struct BBox {
    double x_min, y_min, x_max, y_max;
    BBox(){};
    BBox(double x_min, double y_min, double x_max, double y_max) : x_min(x_min), y_min(y_min), x_max(x_max), y_max(y_max){};
};
struct AxisGrid {
    QVector<QVector<QVector2D>> lines;
    bool show;               // 是否显示
    double precision;        // 精度
    double graph_precision;  // 画布网格精度
    int num_max;             // 网格线最大数量
    int num_min;
    double w;
    int x_left;
    int x_right;
    int y_left;
    int y_right;
    AxisGrid() : show(true), precision(1), graph_precision(1), num_max(50), num_min(30){};
};

struct AxisRuler {
    double width;
    double height;
    double w;
    int num_max;
    int num_min;
    QList<QVector<double>> paths;
    QList<QVector<double>> texts;

    // QMap<QString, QVector2D> paths;

    std::vector<int> a;

    AxisRuler() : width(50), height(50), w(10), num_max(50), num_min(30){};
    AxisRuler(double width, double height) : width(width), height(height), w(10), num_max(50), num_min(30){};
};

struct AxisMatrix {
    double tran_x, tran_y, scale_x, scale_y;
    AxisMatrix(){};
    AxisMatrix(double scale_x, double scale_y, double tran_x, double tran_y) : scale_x(scale_x), scale_y(scale_y), tran_x(tran_x), tran_y(tran_y){};
    void setTranslate(double tran_x, double tran_y) {
        tran_x = tran_x;
        tran_y = tran_y;
    };
    void setScale(double scale_x, double scale_y) {
        scale_x = scale_x;
        scale_y = scale_y;
    };
};

class Axis {
public:
    Axis();
    ~Axis();

    void init(int width_, int height_, double unit_, double precision_);

    void setCenter();
    Point getGridAdsorpPoint();
    void getGridLine();
    void getRulerX();
    void getRulerY();
    QVector2D getMousePixelXY() {
        return QVector2D(mouse_pixel_x, mouse_pixel_y);
    };
    QVector2D getZeroPixelXY() {
        return QVector2D(zero_pixel_x, zero_pixel_y);
    };
    QVector2D getPosXY() {
        return QVector2D(pos_x, pos_y);
    };
    QVector2D getPosRealXY() {
        return QVector2D(pos_real_x, pos_real_y);
    };
    QVector2D getRealXY() {
        return QVector2D(real_x, real_y);
    };
    QVector2D getTranXY() {
        return QVector2D(dx, dy);
    };
    void updateValue();
    // void onMouseMove(QMouseEvent *e);
    void tranlate(float dx, float dy);
    void onMouseMove(float x, float y);
    void onMouseWheel(QWheelEvent *e);

    void resize(int width_, int height_) {
        width = width_;
        height = height_;
        dx = width / 2.0;
        dy = height / 2.0;
    };
    void setWidth(int width_) {
        width = width_;
    };
    void setHeight(int height_) {
        height = height_;
    };
    void setUnit(double unit_) {
        unit = unit_;
    };
    void setPrecision(double precision_) {
        precision = precision_;
    };

    // private:
    int width;
    int height;
    double unit;
    double precision;

    double dx, dy;

    double real_x, real_y;
    double pos_x, pos_y;
    double pos_real_x, pos_real_y;
    double mouse_real_x, mouse_real_y;
    double mouse_pixel_x, mouse_pixel_y;
    double zero_pixel_x, zero_pixel_y;
    double draw_x, draw_y;
    double board_real_x, board_real_y;

    double unit_scale;
    double cell_scale;
    double scale, scale_max, scale_min;
    double line_width;

    AxisMatrix matrix;

    Point mouse_point;

    bool adsorp;
    Point adsorp_point;
    double adsorp_precision;

    AxisGrid grid;
    AxisRuler rulerX;
    AxisRuler rulerY;

    BBox bounds;
    BBox bounds_box;
    BBox bounds_unit;
    BBox bounds_mouse;
    double bounds_mouse_range;
};
}  // namespace qgraphic

#endif  // GLWidget_H
